home *** CD-ROM | disk | FTP | other *** search
/ BCI NET / BCI NET Dec 94.iso / archives / programming / source / fbm12s.lha / fbnorm.c < prev    next >
C/C++ Source or Header  |  1994-07-18  |  6KB  |  197 lines

  1. /*****************************************************************
  2.  * fbnorm.c: FBM Release 1.2 07-Apr-93 Michael Mauldin
  3.  *
  4.  * Copyright (C) 1989-1993 by Michael Mauldin.  Permission is granted
  5.  * to use this file in whole or in part for any purpose, educational,
  6.  * recreational or commercial, provided that this copyright notice
  7.  * is retained unchanged.  This software is available to all free of
  8.  * charge by anonymous FTP and in the UUNET archives.
  9.  *
  10.  * fbnorm.c: Normalize contrast and brightness of image
  11.  *
  12.  * USAGE
  13.  *      % fbnorm < image > image2
  14.  *
  15.  * EDITLOG
  16.  *      LastEditDate = Mon Jun 25 00:03:46 1990 - Michael Mauldin
  17.  *      LastFileName = /usr2/mlm/src/misc/fbm/fbnorm.c
  18.  *
  19.  * HISTORY
  20.  * 07-Apr-93  Michael Mauldin (mlm) at Carnegie-Mellon University
  21.  *    Added -J switch
  22.  *
  23.  * 25-Jun-90  Michael Mauldin (mlm@cs.cmu.edu) Carnegie Mellon
  24.  *    Package for Release 1.0
  25.  *
  26.  * 13-Jun-90  Michael Mauldin (mlm) at Carnegie Mellon University
  27.  *    Final release (version 1.0) mlm@cs.cmu.edu
  28.  *
  29.  * 07-Mar-89  Michael Mauldin (mlm) at Carnegie Mellon University
  30.  *    Beta release (version 0.9) mlm@cs.cmu.edu
  31.  *
  32.  * 21-Aug-88  Michael Mauldin (mlm) at Carnegie-Mellon University
  33.  *      Created.
  34.  *****************************************************************/
  35.  
  36. # include <stdio.h>
  37. # include <math.h>
  38. # include <ctype.h>
  39. # include "fbm.h"
  40.  
  41. # define USAGE \
  42.     "Usage: fbnorm [ -b<val> -w<val> ] [ -<type> ] < image > image"
  43.  
  44. #ifndef lint
  45. static char *fbmid =
  46. "$FBM fbnorm.c <1.2> 07-Apr-93 (C) 1989-1993 by Michael Mauldin, source \
  47. code available free from MLM@CS.CMU.EDU and from UUNET archives$";
  48. #endif
  49.  
  50. main (argc, argv)
  51. char *argv[];
  52. { FBM image;
  53.   register unsigned char *bmptr, *tail;
  54.   register int j, k, ch, size, cnt;
  55.   int min = -1, max = -1, cutoff;
  56.   int hist[BYTE];
  57.   double blackp = -1.0, whitep = -1.0;    /* Percent */
  58.   int outtype = FMT_FBM;
  59.  
  60.   /* Get the options */
  61.   while (--argc > 0 && (*++argv)[0] == '-')
  62.   { while (*++(*argv))
  63.     { switch (**argv)
  64.       { case 'b':       blackp = atof (*argv+1); SKIPARG; break;
  65.         case 'w':       whitep = atof (*argv+1); SKIPARG; break;
  66.     case 'A':    outtype = FMT_ATK; break;
  67.     case 'B':    outtype = FMT_FACE; break;
  68.     case 'F':    outtype = FMT_FBM; break;
  69.     case 'G':    outtype = FMT_GIF; break;
  70.     case 'I':    outtype = FMT_IFF; break;
  71.     case 'J':    outtype = FMT_JPEG; break;
  72.     case 'L':    outtype = FMT_LEAF; break;
  73.     case 'M':    outtype = FMT_MCP; break;
  74.     case 'P':    outtype = FMT_PBM; break;
  75.     case 'R':    outtype = FMT_RLE; break;
  76.     case 'S':    outtype = FMT_SUN; break;
  77.     case 'T':    outtype = FMT_TIFF; break;
  78.     case 'X':    outtype = FMT_X11; break;
  79.     case 'Z':    outtype = FMT_PCX; break;
  80.         default:        fprintf (stderr, "%s\n", USAGE);
  81.                         exit (1);
  82.       }
  83.     }
  84.   }
  85.  
  86.   if (argc == 1)
  87.   { blackp = whitep = atof (argv[0]); }
  88.   else if (argc == 2)
  89.   { min = atoi (argv[0]); max = atoi (argv[1]); }
  90.   else if (argc > 2)
  91.   { fprintf (stderr, "%s\n", USAGE);
  92.     exit (1);
  93.   }
  94.   
  95.   /* Clear the memory pointer so alloc_fbm won't be confused */
  96.   image.cm  = image.bm  = (unsigned char *) NULL;
  97.  
  98.   /* Now read in the image */
  99.   if (read_bitmap (&image, (char *) NULL))
  100.   { 
  101.     /* Check input type */
  102.     if (image.hdr.physbits != 8)
  103.     { fprintf (stderr,
  104.            "Can't normalize images with %d physical bits per pixel\n",
  105.            image.hdr.physbits);
  106.       exit (1);
  107.     }
  108.  
  109.     if (image.hdr.clrlen > 0)
  110.     { fprintf (stderr,
  111.            "Warning, %s\n         %s\n",
  112.            "normalizing a mapped image is probably not what you want",
  113.            "I'll do it anyway, but you should probably use unmap first.");
  114.     }
  115.  
  116.     /* Set default tail sizes */
  117.     if (image.hdr.planes > 1)        /* Color defaults */
  118.     { if (blackp < 0.0) blackp = 0.5;
  119.       if (whitep < 0.0) whitep = 0.5;
  120.     }
  121.     else                /* Bw defaults */
  122.     { if (blackp < 0.0) blackp = 2.0;
  123.       if (whitep < 0.0) whitep = 1.0;
  124.     }
  125.  
  126.     size = image.hdr.rows * image.hdr.cols * image.hdr.planes;
  127.  
  128.     /* Calculate min and max (if not given as arguments) */
  129.     if (min < 0 || max < 0)
  130.     {
  131.       /* Compute histogram */
  132.       for (ch=0; ch<BYTE; ch++)
  133.       { hist[ch] = 0; }
  134.   
  135.       for (k=0; k<image.hdr.planes; k++)
  136.       { for (j=0; j< image.hdr.rows; j++)
  137.         { bmptr = &(image.bm[k*image.hdr.plnlen + j*image.hdr.rowlen]);
  138.           tail = bmptr + image.hdr.cols;
  139.           
  140.           while (bmptr < tail)
  141.           { hist[*bmptr++]++; }
  142.         }
  143.       }
  144.  
  145.       /* Take off 'blackp' percent of darkest pixels */      
  146.       cutoff = size * blackp / 100.0;
  147.  
  148.       for (ch=0, cnt=0; ch<BYTE; ch++)
  149.       { if ((cnt += hist[ch]) > cutoff)
  150.         { min = ch; break; }
  151.       }
  152.  
  153.       /* Take off 'whitep' percent of darkest pixels */      
  154.       cutoff = size * whitep / 100.0;
  155.  
  156.       for (ch = BYTE-1, cnt=0; ch >= 0; ch--)
  157.       { if ((cnt += hist[ch]) > cutoff)
  158.         { max = ch; break; }
  159.       }
  160.     }
  161.       
  162.     fprintf (stderr, "Normalizing: \"%s\" <%d,%d> ==> <0..255>\n",
  163.              image.hdr.title[0] ? image.hdr.title : "(untitled)", min, max);
  164.  
  165.     bmptr = image.bm;
  166.     tail = bmptr+size;
  167.  
  168.     while (bmptr < tail)
  169.     { ch = *bmptr;
  170.  
  171.       if (ch <= min)
  172.       { ch = 0; }
  173.       else if (ch >= max)
  174.       { ch = 255; }
  175.       else
  176.       { ch = (ch - min) * 255 / (max - min); }
  177.  
  178.        if (ch < 0 || ch > 255)
  179.        { fprintf (stderr, "raw %d, min %d, max %d, out %d\n",
  180.                   *bmptr, min, max, ch);
  181.        }
  182.  
  183.       *bmptr++ = ch;
  184.     }
  185.     
  186.     /* The image is now an 8bit per pixel image */
  187.     image.hdr.bits = 8;
  188.  
  189.     /* Write it out */
  190.     write_bitmap (&image, stdout, outtype);
  191.   }
  192.   else
  193.   { exit (1); }
  194.   
  195.   exit (0);
  196. }
  197.